package redis

import (
	"encoding/json"
	"fmt"
	"time"

	"gitee.com/cold777/card_house/pkg"

	"github.com/gomodule/redigo/redis"
)

type RedisPool struct {
	Pool redis.Pool
}

func NewRedisPool(conf *pkg.RedisSettingS) *RedisPool {
	addr := fmt.Sprintf("%s:%d", conf.Host, conf.Port)
	return &RedisPool{Pool: redis.Pool{
		MaxIdle:     conf.MaxIdle,
		IdleTimeout: time.Duration(conf.IdleTimeout) * time.Second,
		// Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial.
		Dial: func() (redis.Conn, error) { return redis.Dial("tcp", addr) },
		// Use the TestOnBorrow function to check the health of an idle connection before the connection is returned to the application. This example PINGs connections that have been idle more than a minute:
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < time.Minute {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
	}}
}

func (p *RedisPool) GetConn() redis.Conn {
	return p.Pool.Get()
}

func (p *RedisPool) Set(key string, value interface{}) error {
	conn := p.GetConn()
	defer conn.Close()

	body, _ := json.Marshal(value)
	_, err := conn.Do("SET", key, string(body))
	return err
}

func (p *RedisPool) Get(key string, dest interface{}) error {
	conn := p.GetConn()
	defer conn.Close()

	body, err := redis.String(conn.Do("GET", key))
	if err != nil {
		return err
	}

	return json.Unmarshal([]byte(body), &dest)
}
